#pragma once
#include "..\DXAMLCommon.h"
#include "Base.h"
#include "InputSource.h"

class CodePageCharacterSource;


class CharacterSource :
	public Base
{
private: 
	virtual CharacterSource & operator=(CharacterSource & __formal);

public: 
	CharacterSource(struct IMalloc * pMalloc);
	virtual ~CharacterSource();
	virtual bool fCodePageSrc();
	void Copy(CharacterSource & pCharSrcSrc);
	virtual bool GetLittleEndian();
	virtual XINT32 GetCharacterSize();
	virtual InputSource * GetInputSource();
	virtual void SetInputSource(InputSource * pInputSource);
	virtual void SetFirstInputBuffer(XUINT8 * pbInput, XUINT8 * pbSeg, unsigned long cbInput, unsigned long cbValid);
	virtual void ReleaseInputBuffer(XUINT8 * * ppbInput, XUINT8 * * ppbSeg, unsigned long * pcbInput, unsigned long * pcbValid);
	bool GetEndOfInput();
	void SetSegment();
	void ResetSegment();
	void SetSegmentDelta(HRESULT);
	void SavePosition();
	void RestorePosition();
	void SetLine(unsigned long);
	unsigned long GetLineCount();
	unsigned long GetCharacterPosition(XUINT8 *);
	unsigned long GetCharacterPosition();
	XUINT64 GetStreamPosition();
	virtual void GetExtendedPosition(struct Position * pPosition);
	virtual void SetExtendedPosition(struct Position * pPosition);
	XUINT8 GetByte();
	virtual wchar_t GetCharacter() = 0;
	virtual XINT32 GetSegmentSize() = 0;
	virtual void GetSegmentValue(struct StringPtr *) = 0;
	virtual unsigned long GetCharacterOffset(XUINT8 *, XUINT8 *) = 0;
	virtual bool GetCharacterIfEqual(char) = 0;
	virtual void FixAsciiCharacter(char chNewChar);
	virtual enum XCharScanEnum ScanWS(XINT32 *) = 0;
	virtual enum XCharScanEnum ScanCharData(XINT32 *) = 0;
	virtual void CheckCDSectEnd() = 0;
	virtual const XUINT8 * XmlDecl(XUINT32 *) = 0;
	void SetInXmlDecl(bool);
protected: 
	virtual void CopyFrom(CharacterSource & other);
	virtual void CopyFrom(CodePageCharacterSource & other);
	unsigned long Pull();
	unsigned long PullAhead();
	void RecomputeGrowMark();
	static void __stdcall ValidateCapacity(unsigned long);
private: 
	unsigned long Fill();
	void Grow();
	void Shift();
protected: 
	InputSource * _pInputSource;
	bool _fEndOfInput;
	bool _fXmlDecl;
	unsigned long _ulCapacity;
	unsigned long _ulGrowMark;
	XUINT8 * _pbStart;
	XUINT8 * _pbCurr;
	XUINT8 * _pbSeg;
	XUINT8 * _pbEnd;
	XUINT8 * _pbSaved;
	XUINT8 * _pbLastRead;
	HRESULT _lDelta;
	XUINT8 * _pbLine;
	unsigned long _ulLine;
	XUINT8 * _pbLineShifted;
	unsigned long _ulCharPosShifted;
	XUINT64 _ullStartPosition;

};